#include "graphic_extension_manager.h"
/*--------------------------------------------------------------------------------*/
#include "primitives.h"
#include "object.h"
#include "util.h"
#include "debug.h"
#include <GL/glu.h>
#include <GL/glext.h>
#include <cstdio>
#include <SDL/SDL.h>
#include "graphic_vertex_buffer.h"
#include "graphic_shader.h"
#include "graphic_shader_program.h"
/*--------------------------------------------------------------------------------*/
const char *LOCAL_GraphicExtensionName[] =
{
	"GL_ARB_vertex_buffer_object",
	"GL_ARB_shading_language_100",
	"GL_ARB_shader_objects",
	"GL_ARB_vertex_shader",
	"GL_ARB_fragment_shader"
};
/*--------------------------------------------------------------------------------*/
IMPLEMENT_SINGLETON( GRAPHIC_EXTENSION_MANAGER );
/*--------------------------------------------------------------------------------*/
VOID GRAPHIC_EXTENSION_MANAGER::Initialize()
{
	INDEX
		char_index,
		extension_index;
	TEXT
		extensions( (const char *)glGetString( GL_EXTENSIONS ) );
	TEXT
		current_extension;

	ExtensionIsEnabledTable.Clear();
	current_extension.Clear();

	for_each_index( char_index , extensions.GetLength() )
	{
		if( extensions[ char_index ] == ' ' )
		{
			for_each_table_index( extension_index, ExtensionIsEnabledTable )
			{
				if( current_extension == LOCAL_GraphicExtensionName[ extension_index ] )
				{
					ExtensionIsEnabledTable[ extension_index ] = true;
				}
			}
			
			current_extension.Clear();
		}
		else
		{
			current_extension.Add( extensions[ char_index ] );
		}
	}

	if( IsExtensionSupported( GRAPHIC_EXTENSION_VertexBufferObject ) )
	{
		GRAPHIC_VERTEX_BUFFER::glGenBuffers = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress( "glGenBuffersARB" );
		GRAPHIC_VERTEX_BUFFER::glBindBuffer = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress( "glBindBufferARB" );
		GRAPHIC_VERTEX_BUFFER::glBufferData = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress( "glBufferDataARB" );
		GRAPHIC_VERTEX_BUFFER::glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB" );

		DEBUG_Require( GRAPHIC_VERTEX_BUFFER::glGenBuffers && GRAPHIC_VERTEX_BUFFER::glBindBuffer && GRAPHIC_VERTEX_BUFFER::glBufferData && GRAPHIC_VERTEX_BUFFER::glDeleteBuffers );


		DEBUG_LogLine("Vertex buffer object supported.");
	}
	else
	{
		DEBUG_LogLine("Vertex buffer object unsupported!");
	}

	if( IsExtensionSupported( GRAPHIC_EXTENSION_VertexShader )
		&& IsExtensionSupported( GRAPHIC_EXTENSION_FragmentShader )
		&& IsExtensionSupported( GRAPHIC_EXTENSION_ShaderObjects )
		&& IsExtensionSupported( GRAPHIC_EXTENSION_ShadingLanguage100 ) )
	{
		GRAPHIC_SHADER::glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress( "glCreateShader" );
		GRAPHIC_SHADER::glDeleteShader = (PFNGLDELETESHADERPROC) SDL_GL_GetProcAddress( "glDeleteShader" );
		GRAPHIC_SHADER::glShaderSource = (PFNGLSHADERSOURCEPROC) SDL_GL_GetProcAddress( "glShaderSource" );
		GRAPHIC_SHADER::glCompileShader = (PFNGLCOMPILESHADERPROC) SDL_GL_GetProcAddress( "glCompileShader" );
		GRAPHIC_SHADER::glGetShaderiv = (PFNGLGETSHADERIVPROC) SDL_GL_GetProcAddress( "glGetShaderiv" );
		GRAPHIC_SHADER::glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress( "glGetShaderInfoLog" );

		GRAPHIC_SHADER_PROGRAM::glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress( "glCreateProgram" );
		GRAPHIC_SHADER_PROGRAM::glDeleteProgram = (PFNGLDELETEPROGRAMPROC) SDL_GL_GetProcAddress( "glDeleteProgram" );
		GRAPHIC_SHADER_PROGRAM::glAttachShader = (PFNGLATTACHSHADERPROC) SDL_GL_GetProcAddress( "glAttachShader" );
		GRAPHIC_SHADER_PROGRAM::glDetachShader = (PFNGLDETACHSHADERPROC) SDL_GL_GetProcAddress( "glDetachShader" );
		GRAPHIC_SHADER_PROGRAM::glLinkProgram = (PFNGLLINKPROGRAMPROC) SDL_GL_GetProcAddress( "glLinkProgram" );
		GRAPHIC_SHADER_PROGRAM::glGetProgramiv = (PFNGLGETPROGRAMIVPROC) SDL_GL_GetProcAddress( "glGetProgramiv" );
		GRAPHIC_SHADER_PROGRAM::glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) SDL_GL_GetProcAddress( "glGetProgramInfoLog" );
		GRAPHIC_SHADER_PROGRAM::glUseProgram = (PFNGLUSEPROGRAMPROC) SDL_GL_GetProcAddress( "glUseProgram" );

		DEBUG_Require( GRAPHIC_SHADER::glCreateShader );
		DEBUG_Require( GRAPHIC_SHADER::glDeleteShader );
		DEBUG_Require( GRAPHIC_SHADER::glShaderSource );
		DEBUG_Require( GRAPHIC_SHADER::glCompileShader );
		DEBUG_Require( GRAPHIC_SHADER::glGetShaderiv );
		DEBUG_Require( GRAPHIC_SHADER::glGetShaderInfoLog );

		DEBUG_Require( GRAPHIC_SHADER_PROGRAM::glCreateProgram );

		DEBUG_LogLine("Shaders supported.");
	}
	else
	{
		DEBUG_LogLine("Shaders unsupported.");
	}
}
/*--------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------*/

